/*
//
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//    Copyright (c) 2007 Intel Corporation. All Rights Reserved.
//
//
*/

#ifndef __UMC_AVS_DEC_DECOMPRESSOR_H
#define __UMC_AVS_DEC_DECOMPRESSOR_H

#include "ippdefs.h"
#include "ippvc.h"
#include "umc_avs_context.h"
#include "umc_avs_mb_info.h"
#include "umc_avs_dec_additional_info.h"

namespace UMC
{

// forward declaration of used types
class AVSPicture;

struct AVS_NEIGHBOURS
{
    AVS_MB_INFO *pNearest;

    AVS_MB_INFO *pLeft;
    AVS_MB_INFO *pTop;
    AVS_MB_INFO *pTopRight;
    AVS_MB_INFO *pTopLeft;
};

class AVSDecompressor
{
public:
    // Default constructor
    AVSDecompressor(void);
    // Destructor
    virtual
    ~AVSDecompressor(void);

    //
    // Initialization functions
    //

    // Set decoding parameters
    inline
    void SetDecodingContext(AVS_DECODING_CONTEXT &decCtx);
    // Get decoding parameters
    inline
    AVS_DECODING_CONTEXT & GetDecodingContext(void);
    // Set reconstructing parameters
    inline
    void SetReconstructingContext(AVS_RECONSTRUCTING_CONTEXT &recCtx);
    // Get reconstructing parameters
    inline
    AVS_RECONSTRUCTING_CONTEXT & GetReconstructingContext(void);

    //
    // Decoding functions
    //
    void DecodeIMacroBlocksRow(void);
    void DecodePMacroBlocksRow(void);
    void DecodeBMacroBlocksRow(void);


    //
    // Reconstructing functions
    //
    void ReconstructIMacroBlocksRow(void);
    void ReconstructPMacroBlocksRow(void);
    void ReconstructBMacroBlocksRow(void);


    //
    // Combined function (used for single-threaded version)
    //
    void DecompressIMacroBlocksRow(void);
    void DecompressPMacroBlocksRow(void);
    void DecompressBMacroBlocksRow(void);

protected:

    // Prepare pointers to neighbours macroblock info
    void PrepareNeighbours(AVS_BASE_CONTEXT *pCtx);
    // Prepare decoding variables
    void PrepareDecoding(bool isThreaded = false);
    // Prepare reconstructing variables
    void PrepareReconstruction(bool isThreaded = false);

    // Reset the macroblock parameters before its decoding
    void ResetMacroblock();

    // Update affected area of references
    void UpdateAffectedArea(void);
    // Advance pointers to neighbours macroblocks
    void AdvanceNeighbours(void);
    // Update decoding variables
    void AdvanceDecoding(void);
    // Update reconstructing variables
    void AdvanceReconstruction(void);

    // Finalize decoding stuff, set specials flags
    void FinalizeDecoding(void);
    // Finalize reconstructing stuff, set specials flags
    void FinalizeReconstruction(void);

    void DecodeIMacroBlock(void);
    void DecodePMacroBlock(void);
    void DecodeBMacroBlock(void);

    void DecodeSkipPMacroBlock(void);
    void DecodeSkipBMacroBlock(void);

    void ReconstructIMacroBlock(void);
    void ReconstructPMacroBlock(void);
    void ReconstructBMacroBlock(void);

    void DecodeIMacroBlockType(void);
    void DecodePMacroBlockType(void);
    void DecodeBMacroBlockType(void);

    // Specify intra prediction mode
    void SetIntraPredModeISlice(AVS_MB_INFO *pLeft, AVS_MB_INFO *pTop, Ipp32s iBlockNum);
    // Specify reference indices
    void SetRefIndiciesPSlice(void);
    void SetRefIndiciesBSlice(void);
    // Reconstruct motion vectors from differencies
    void ReconstructMotionVectorsPSlice(void);
    void ReconstructMotionVectorsBSlice(void);
    void ReconstructMotionVectorsBSlice16x16(void);
    void ReconstructMotionVectorsBSlice16x8(void);
    void ReconstructMotionVectorsBSlice8x16(void);
    void ReconstructMotionVectorsBSlice8x8(void);
    virtual
    void ReconstructMotionVectorsBSliceDirect(void);
    eAVSDivBlockType GetCollocatedBlockDivision(void);
    virtual
    void ReconstructDirectMotionVector(Ipp32s blockNum);
    virtual
    void CreateSymmetricalMotionVector(Ipp32s blockNum);
    // Specify  motion vector predictor
    void GetMotionVectorPredictor16x16(eAVSPredType predType, Ipp32s blockNum);
    void GetMotionVectorPredictor16x8(eAVSPredType predType, Ipp32s blockNum);
    void GetMotionVectorPredictor8x16(eAVSPredType predType, Ipp32s blockNum);
    void GetMotionVectorPredictor8x8(eAVSPredType predType, Ipp32s blockNum);
    void GetMotionVectorPredictor(AVSMVector mvA, AVSMVector mvB, AVSMVector mvC,
                                  Ipp32s blockDist,
                                  Ipp32s blockDistA, Ipp32s blockDistB, Ipp32s blockDistC);

    // Compensate motion functions
    void CompensateMotionLumaPMacroBlock(void);
    void CompensateMotionLumaBMacroBlock(void);
    void CompensateMotionLumaUniDir(Ipp32s blockNum, eAVSPredType predType);
    void CompensateMotionLumaBiDir(Ipp32s blockNum);
    void CompensateMotionChromaPMacroBlock(void);
    void CompensateMotionChromaBMacroBlock(void);
    void CompensateMotionChromaUniDir(Ipp32s blockNum, eAVSPredType predType);
    void CompensateMotionChromaBiDir(Ipp32s blockNum);

    AVS_DECODING_CONTEXT m_decCtx;                              // (AVS_DECODING_CONTEXT) decoding context
    AVS_RECONSTRUCTING_CONTEXT m_recCtx;                        // (AVS_RECONSTRUCTING_CONTEXT) reconstructing context

    //
    // common members
    //
    Ipp32s MbIndex;                                             // (Ipp32s) index of being decoded macroblock
    Ipp32s MbMax;                                               // (Ipp32s) index of last macroblock in row
    AVS_MB_INFO *m_pMbInfo;                                     // (AVS_MB_INFO *) current macroblock's properties
    AVS_MB_INFO *m_pMbInfoLeft;                                 // (AVS_MB_INFO *) left macroblock's properties
    AVS_MB_INFO *m_pMbInfoTop;                                  // (AVS_MB_INFO *) upper macroblock's properties
    AVS_MB_INFO *m_pMbInfoTopRight;                             // (AVS_MB_INFO *) upper-right macroblock's properties
    AVS_MB_INFO *m_pMbInfoTopLeft;                              // (AVS_MB_INFO *) upper-left macroblock's properties

    //
    // decoding members
    //
    Ipp16s *m_pWriteCoeffs;
    Ipp8u pred_mode_flag[4];                                    // (Ipp8u []) flag means prediction type exists in bitstream
    Ipp8s intra_luma_pred_mode[4];                              // (Ipp8s []) luminance prediction modes
    AVSMVector mv_diff[4];                                      // (AVSMVector []) motion vector differences
    Ipp32u m_refIdx[4];                                         // (Ipp32u []) decoded reference indices
    AVS_DEC_ADDITIONAL_INFO *m_pExtraInfo;                      // (AVS_DEC_ADDITIONAL_INFO *) pointer to a piece of additional info of MB row

    //
    // reconstructing members
    //
    const Ipp16s *m_pReadCoeffs;
    AVSPicture *(m_pRefs[AVS_DIRECTIONS][4]);                   // (AVSPicture *([])) array of pointers to reference frames
    Ipp32s m_blockDist[AVS_DIRECTIONS][4];                      // (Ipp32s [][]) block distances, depending on ref index
    Ipp32s m_distIdx[AVS_DIRECTIONS][4];                        // (Ipp32s [][]) distance indecies of reference pictures

    AVSMVector m_mvPred;                                        // (AVSMVector) motion vector prediction
    AVS_NEIGHBOURS m_neighbours;                                // (AVS_NEIGHBOURS) neighbours of current block

    IppVCInterpolateBlock_8u m_lumaMCParams;                    // (IppVCInterpolateBlock_8u) luminance interpolation parameters
    IppVCInterpolateBlock_8u m_chromaMCParams;                  // (IppVCInterpolateBlock_8u) chrominance interpolation parameters

    union
    {
    Ipp8u *(m_pPlanes8u[3]);                                    // (Ipp8u *([])) array of pointers to picture's planes
    Ipp16u *(m_pPlanes16u[3]);                                  // (Ipp16u *([])) array of pointers to picture's planes
    };
    Ipp32s m_iPitch;                                            // (Ipp32s) pitch of planes

};

inline
void AVSDecompressor::SetDecodingContext(AVS_DECODING_CONTEXT &decCtx)
{
    m_decCtx = decCtx;

} // void AVSDecompressor::SetDecodingContext(AVS_DECODING_CONTEXT &decCtx)

inline
AVS_DECODING_CONTEXT & AVSDecompressor::GetDecodingContext(void)
{
    return m_decCtx;

} // AVS_DECODING_CONTEXT & AVSDecompressor::GetDecodingContext(void)

inline
void AVSDecompressor::SetReconstructingContext(AVS_RECONSTRUCTING_CONTEXT &recCtx)
{
    m_recCtx = recCtx;

} // void AVSDecompressor::SetReconstructingContext(AVS_RECONSTRUCTING_CONTEXT &recCtx)

inline
AVS_RECONSTRUCTING_CONTEXT & AVSDecompressor::GetReconstructingContext(void)
{
    return m_recCtx;

} // AVS_RECONSTRUCTING_CONTEXT & AVSDecompressor::GetReconstructingContext(void)

} // namespace UMC

#endif // __UMC_AVS_DEC_DECOMPRESSOR_H
